/************************************
 文件明 ：  bsp_clk.c
 作者   ：  胡秋峰
 描述   ：  系统时钟驱动文件
 ************************************/
#include "bsp_clk.h"

/**
 * @描述    ： 是能所有外设时钟
 * @参数    ： 无
 * @返回值  ： 无 
 */
void clk_enable() 
{
    CCM->CCGR0 = 0xFFFFFFFF;
    CCM->CCGR1 = 0XFFFFFFFF;

    CCM->CCGR2 = 0XFFFFFFFF;
    CCM->CCGR3 = 0XFFFFFFFF;
    CCM->CCGR4 = 0XFFFFFFFF;
    CCM->CCGR5 = 0XFFFFFFFF;
    CCM->CCGR6 = 0XFFFFFFFF;
}

/**
 * @描述    ： 初始化系统时钟528MHZ，并设置PLL2和PLL3各个
 *             PDF时钟，所有的时钟频率均按照官方推荐值
 * @参数    ： 无
 * @返回值  ： 无 
 */
void imx6u_clk_init(void)
{
    uint32_t reg;
    
    /* 1、设置ARM内核时钟为528MHZ */
    if ((((CCM->CCSR) >> 2) & 0x1) == 0) { /* pull1_main_clk */
        CCM->CCSR &= ~(0x1 << 8); /* 配置step_clk时钟频率为24MHZ */
        CCM->CCSR |= (0x1 << 2); /* 配置pull1sw_clk时钟源为step_clk */
    }
    /* 设置pull1_main_clk时钟频率为1056MHZ */
    CCM_ANALOG->PLL_ARM = (1 << 13) | ((88 < 0) & 0x7f);
    CCM->CCSR &= ~(0x1 << 2); /* 将pull_sw_clk切换为pull1_main_clk */
    CCM->CACRR = 1; /* ARM内核时钟为pull1_main_clk/2 = 1056/2 =528MHZ */

    /* 2、设置PLL2(SYS PLL)各个PFD */
    reg = CCM_ANALOG->PFD_528;
    reg &= ~(0x3f3f3f3f);   /* 清除原来的设置 */
    reg |= (32 << 24);      /* PLL2_PFD3=528*18/32=297MHZ */
    reg |= (24 << 16);      /* PLL2_PFD3=528*18/24=396MHZ */
    reg |= (16 << 8);       /* PLL2_PFD3=528*18/16=594MHZ */
    reg |= (27 << 0);       /* PLL2_PFD3=528*18/27=352MHZ */
    CCM_ANALOG->PFD_528 = reg;

    /* 3、设置PLL3(USB1)各个PFD */
    reg = CCM_ANALOG->PFD_480;
    reg &= ~(0x3f3f3f3f);   /* 清除原来的设置 */
    reg |= (19 << 24);      /* PLL2_PFD3=480*18/19=454.74MHZ */
    reg |= (17 << 16);      /* PLL2_PFD3=480*18/17=508.24MHZ */
    reg |= (16 << 8);       /* PLL2_PFD3=480*18/16=540MHZ */
    reg |= (12 << 0);       /* PLL2_PFD3=480*18/12=720MHZ */
    CCM_ANALOG->PFD_480 = reg;

    /* 4、设置AHB时钟最大132MHZ、最小6MHZ */
    CCM->CBCMR &= ~(3 << 18); /* 清除设置 */
    CCM->CBCMR |= (1 << 18);  /* pre_periph_clk=PLL2_PFD2=396MHZ */
    CCM->CBCDR &= ~(1 << 25); /* periph_clk = pre_periph_clk = 396MHZ */
    while (CCM->CDHIPR & (1 << 5)); /* 等待握手完成 */

    /* 5、设置IPG_CLK_ROOT最小3MHZ、最大66MHZ */
    CCM->CBCDR &= ~(3 << 8); /* CBCDR的IPG_PODF清零 */
    CCM->CBCDR |= (1 << 8);  /* IPG_PODF 2分频， IPG_CLK_ROOT = 66MHZ */

    /* 6、设置PERCLK_CLK_ROOT时钟 */
    CCM->CSCMR1 &= ~(1 << 6); /* PERCLK_CLK_ROOT时钟源为IPG */
    CCM->CSCMR1 &= ~(7 << 0); /* PERCLK_PODF位清零，即1分频 */
    
}